//
//  MZSuspensionBall.m
//  HealthStarApp
//
//  Created by zhumuzhi on 2021/3/4.
//  Copyright © 2021 zhumuzhi. All rights reserved.
//  悬浮球

#import "SuspensionBall.h"

/**
 按钮事件类型
 DockTypeNone       自动识别贴边
 DockTypeNearLeft   拖动停止之后，自定向左贴边
 DockTypeNearRight  拖动停止之后，自定向右贴边
 */
typedef NS_ENUM (NSUInteger, DockType) {
    DockTypeNone = 0,
    DockTypeNearLeft,
    DockTypeNearRight,
};

static CGFloat SuspensionViewWH = 40;   // 悬浮球宽高
static CGFloat limitMargin = 100;       // limit距离
static SuspensionBall *_suspensionBall;

@interface SuspensionBall ()
{
    DockType    _type;
    CGPoint     _touchPoint;
    CGFloat     _touchPointX;
    CGFloat     _touchPointY;
}
@end

@implementation SuspensionBall

#pragma mark - PublicMethod
+ (instancetype)shared {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _suspensionBall = [[SuspensionBall alloc] initWithType:DockTypeNone frame:CGRectZero];
    });
    return _suspensionBall;
}

- (void)show {
    UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
    [window addSubview:_suspensionBall];
    [window bringSubviewToFront:_suspensionBall];
}

- (void)dissmiss {
    [_suspensionBall removeFromSuperview];
}

#pragma mark - Init
- (instancetype)initWithType:(DockType)type
                       frame:(CGRect)frame {
    if (CGRectEqualToRect(frame, CGRectZero)) {
        CGFloat suspensionButtonX = 0;
        CGFloat suspensionButtonY = [UIScreen mainScreen].bounds.size.height - 200;
        frame = CGRectMake(suspensionButtonX, suspensionButtonY, SuspensionViewWH, SuspensionViewWH);
    }
    if (self == [super initWithFrame:frame]) {
        _type = type;
        self.backgroundColor = [UIColor lightGrayColor];
        [self addTapAction:self selector:@selector(suspensionViewClicked)];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    _suspensionBall.layer.cornerRadius = SuspensionViewWH/2;
    _suspensionBall.layer.masksToBounds = YES;
}


#pragma mark - Event
- (void)suspensionViewClicked {
    if(self.ballBlock) {
        self.ballBlock();
    }
}

#pragma mark - TouchEvent

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    
    UITouch *touch = [touches anyObject];
    _touchPoint = [touch locationInView:self];
    _touchPointX = self.frame.origin.x;
    _touchPointY = self.frame.origin.y;
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    UITouch *touch = [touches anyObject];
    CGPoint currentPosition = [touch locationInView:self];
    CGFloat offsetX = currentPosition.x - _touchPoint.x;
    CGFloat offsetY = currentPosition.y - _touchPoint.y;
    CGFloat centerX = self.center.x + offsetX;
    CGFloat centerY = self.center.y + offsetY;
    self.center = CGPointMake(centerX, centerY);
    
    if(centerY < limitMargin) {
        centerY = limitMargin;
    }
    if (centerY > [UIScreen mainScreen].bounds.size.height - limitMargin) {
        centerY = [UIScreen mainScreen].bounds.size.height - limitMargin;
    }
    
    CGFloat superViewWidth = self.superview.frame.size.width;
    CGFloat superViewHeight = self.superview.frame.size.height;
    CGFloat btnX = self.frame.origin.x;
    CGFloat btnY = self.frame.origin.y;
    CGFloat btnW = self.frame.size.width;
    CGFloat btnH = self.frame.size.height;
    
    if (btnX > superViewWidth) {
        CGFloat centerX = superViewWidth - btnW/2;
        self.center = CGPointMake(centerX, centerY);
    }else if (btnX < 0) {
        CGFloat centerX = btnW * 0.5;
        self.center = CGPointMake(centerX, centerY);
    }
    
    CGFloat defaultNaviHeight = 64;
    CGFloat judgeSuperViewHeight = superViewHeight - defaultNaviHeight;
    
    if (btnY <= 0) {
        centerY = btnH * 0.7;
        self.center = CGPointMake(centerX, centerY);
    } else if (btnY > judgeSuperViewHeight) {
        CGFloat y = superViewHeight - btnH * 0.5;
        self.center = CGPointMake(btnX, y);
    }
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    CGFloat buttonX = self.frame.origin.x;
    CGFloat buttonY = self.frame.origin.y;
    CGFloat buttonW = self.frame.size.width;
    CGFloat buttonH = self.frame.size.height;
    
    if(buttonY < limitMargin) {
        buttonY = limitMargin;
    }
    if (buttonY > [UIScreen mainScreen].bounds.size.height - limitMargin) {
        buttonY = [UIScreen mainScreen].bounds.size.height - limitMargin;
    }
    
    CGFloat minDistance = 2;
    
    // 结束move的时候，计算移动的距离是 > 最低要求，如果没有，就调用按钮点击事件
    BOOL isOverX = fabs(buttonX - _touchPointX) > minDistance;
    BOOL isOverY = fabs(buttonY - _touchPointY) > minDistance;
    
    if (isOverX || isOverY) {
        [self touchesCancelled:touches withEvent:event];
    }else {
        [super touchesEnded:touches withEvent:event];
    }
    switch (_type) {
        case DockTypeNone: {
            if(self.center.x > self.superview.frame.size.width/2) {
                [UIView animateWithDuration:0.25 animations:^{
                    CGFloat buttonX = self.superview.frame.size.width - buttonW;
                    self.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
                }];
            }else {
                [UIView animateWithDuration:0.25 animations:^{
                    CGFloat buttonX = 0;
                    self.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
                }];
            }
            break;
        }
            
        case DockTypeNearLeft: {
            [UIView animateWithDuration:0.25 animations:^{
                CGFloat buttonX = 0;
                self.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
            }];
            break;
        }
            
        case DockTypeNearRight: {
            [UIView animateWithDuration:0.25 animations:^{
                CGFloat buttonX = 0;
                self.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
            }];
            break;
        }
            
        default:
            break;
    }
}


@end
